package com.joint.base.dao.impl;

import com.fz.us.base.bean.BaseEnum;
import com.fz.us.base.bean.Pager;
import com.google.common.collect.Lists;
import com.joint.base.bean.FlowEnum;
import com.joint.base.dao.BaseFlowDao;
import com.joint.base.entity.BusinessConfig;
import com.joint.base.entity.Users;
import com.joint.base.parent.BaseFlowEntity;
import com.joint.base.service.BusinessConfigService;
import com.joint.base.service.UsersService;
import com.joint.base.service.activiti.WorkflowService;
import org.activiti.engine.HistoryService;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by hpj on 2014/12/22.
 */
@Repository
public class BaseFlowDaoImpl<T extends BaseFlowEntity,PK extends Serializable> extends BaseEntityDaoImpl<T,PK> implements BaseFlowDao<T, PK> {
    @Resource
    protected WorkflowService workflowService;
    @Resource
    protected HistoryService historyService;
    @Resource
    protected UsersService usersService;
    @Resource
    protected BusinessConfigService businessConfigService;

    @Override
    public Pager findByPagerAndDraft( Users users, Pager pager, BaseEnum.StateEnum... states) {
        //草稿箱中所有当前人的单子
        List<String> idList = workflowService.findDocIdByNum(0,users);
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(entityClass);
        detachedCriteria.add(Restrictions.eq("processState", FlowEnum.ProcessState.Draft));
        if(idList.size()>0){
            detachedCriteria.add(Restrictions.in("id", idList));
        }else{
            return pager;
        }

        if(states!=null&&states.length>0){
            Criterion[] criterions = new Criterion[states.length];
            for(int i=0;i<states.length;i++){
                criterions[i]= Restrictions.eq("state", states[i]);
            }
            detachedCriteria.add(Restrictions.or(criterions));
        }
        return findByPager(pager, detachedCriteria);
    }

    @Override
    public Pager findByPagerAndLimit(BusinessConfig bcfg,Pager pager, BaseEnum.StateEnum... states) {
        Users users = usersService.getLoginInfo();

        List<String> bussinessList = workflowService.getAllInProcessByUsers(bcfg, users);

        //计算当前人员可见的版本号
        List<BusinessConfig> bcList= businessConfigService.getDocByUser(bcfg, users);
        List<Integer> vList = Lists.newArrayList();
        for(BusinessConfig bcf:bcList){
            vList.add(bcf.getVersion());
        }
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(entityClass);
        if(bussinessList.size() >0){
            detachedCriteria.add(Restrictions.in("id", bussinessList));
            if(bcfg.getPtype()==1){
                //判断业务的version是否在cfg对应的version
                detachedCriteria.add(Restrictions.in("version", vList));
            }
        }else {
            return pager;
        }
        if(states!=null&&states.length>0){
            Criterion[] criterions = new Criterion[states.length];
            for(int i=0;i<states.length;i++){
                criterions[i]= Restrictions.eq("state", states[i]);
            }
            detachedCriteria.add(Restrictions.or(criterions));
        }


        return findByPager(pager, detachedCriteria);
    }

    @Override
    public Pager findByPagerAndFinish(BusinessConfig bcfg,Pager pager, BaseEnum.StateEnum... states) {
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(entityClass);
        Users users = usersService.getLoginInfo();
        // 所有已归档的单子
        List<String> bussinessList = workflowService.getAllInFinishByUsers(bcfg);

        List<BusinessConfig> readList= businessConfigService.getDocReadByUser(bcfg,users);
        List<BusinessConfig> editList= businessConfigService.getDocEditByUser(bcfg,users);
        List<BusinessConfig> docList= businessConfigService.getDocByUser(bcfg,users);

        Set<Integer> vList =new HashSet<Integer>();
        for(BusinessConfig bcf:readList){
            vList.add(bcf.getVersion());
        }
        for(BusinessConfig bcf:editList){
            vList.add(bcf.getVersion());
        }
        for(BusinessConfig bcf:docList){
            vList.add(bcf.getVersion());
        }

        if(vList.size()==0){
            return pager;
        }
        if(bussinessList.size() >0){
            detachedCriteria.add(Restrictions.in("id", bussinessList));
            if(bcfg.getPtype()==1){
                //判断业务的version是否在cfg对应的version
                detachedCriteria.add(Restrictions.in("version", vList));
            }
        }else {
            return pager;
        }
        detachedCriteria.addOrder(Order.desc("createDate"));
        if(states!=null&&states.length>0){
            Criterion[] criterions = new Criterion[states.length];
            for(int i=0;i<states.length;i++){
                criterions[i]= Restrictions.eq("state", states[i]);
            }
            detachedCriteria.add(Restrictions.or(criterions));
        }


        return findByPager(pager, detachedCriteria);
    }

    @Override
    public Pager findByPagerAndBack(Pager pager, BaseEnum.StateEnum... states) {
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(entityClass);
        // 所有已归档的单子
        List<String> bussinessList = workflowService.getAllInBackByUsers();
        if(bussinessList.size() >0){
            detachedCriteria.add(Restrictions.in("id", bussinessList));
        }else {
            return pager;
        }
        detachedCriteria.add(Restrictions.eq("processState", FlowEnum.ProcessState.Backed));
        if(states!=null&&states.length>0){
            Criterion[] criterions = new Criterion[states.length];
            for(int i=0;i<states.length;i++){
                criterions[i]= Restrictions.eq("state", states[i]);
            }
            detachedCriteria.add(Restrictions.or(criterions));
        }


        return findByPager(pager, detachedCriteria);
    }
}
